package top.i51213.fastaction.action.print;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;

import com.itextpdf.text.Document;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import top.i51213.fastaction.action.pdf.MyPdfReader;
import top.i51213.fastaction.uri.UriReader;
import top.i51213.fastaction.util.IOUtil;

public class PdfPrintDocumentAdapter extends PrintDocumentAdapter {
    private final Context context;
    private final List<Uri> list;
    private final String taskName;
    private int duplexMode;

    public PdfPrintDocumentAdapter(Context context, List<Uri> list, String taskName) {
        this.context = context;
        this.list = list;
        this.taskName = taskName;
    }

    @Override
    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
        if (cancellationSignal.isCanceled()) {
            callback.onLayoutCancelled();
            return;
        }
        duplexMode = newAttributes.getDuplexMode();
        int pages = list.size();
        if (pages > 0) {
            // Return print information to print framework
            PrintDocumentInfo info = new PrintDocumentInfo
                    .Builder(taskName + ".pdf")
                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                    .setPageCount(pages).build();
            // Content layout reflow is complete
            callback.onLayoutFinished(info, true);
        } else {
            // Otherwise report an error to the print framework
            callback.onLayoutFailed("Page count calculation failed.");
        }
    }

    @Override
    public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) {
        Document document = new Document();
        try {
            PdfCopy pdfCopy = new PdfCopy(document, new BufferedOutputStream(new FileOutputStream(destination.getFileDescriptor())));
            pdfCopy.setPdfVersion(PdfWriter.PDF_VERSION_1_4);
            document.open();

            for (int i = 0; i < list.size(); i++) {
                Uri uri = list.get(i);
                //System.out.println(uri);
                if (cancellationSignal.isCanceled()) {
                    callback.onWriteCancelled();
                    //System.out.println("打印取消");
                    document.close();
                    return;
                }
                UriReader uriReader = new UriReader(context, uri);
                MyPdfReader pdfReader = new MyPdfReader(uriReader.openInputStream());

                boolean b = (!pdfReader.isOpenedWithFullPermissions()) && pdfReader.isEncrypted();
                System.out.println("加密:" + b);
                if (b) {
                    //pdfReader = removeCrypto(context, pdfReader);
                    pdfReader.decryptOnPurpose();
                    b = (!pdfReader.isOpenedWithFullPermissions()) && pdfReader.isEncrypted();
                    System.out.println("加密(2):" + b);
                }
                int pageCount = pdfReader.getNumberOfPages();
                pdfCopy.addDocument(pdfReader);
                if (i < list.size() - 1 && PrintAttributes.DUPLEX_MODE_NONE != duplexMode && (pageCount & 1) == 1) {
                    //System.out.println("双面打印模式下，存在单页");
                    int rotation = pdfReader.getPageRotation(pageCount);
                    Rectangle rect = pdfReader.getPageSize(pageCount);
                    pdfCopy.addPage(rect, rotation);
                }
                pdfReader.close();
            }
            pdfCopy.close();
            document.close();
            callback.onWriteFinished(new PageRange[]{new PageRange(0, list.size() - 1)});
        } catch (Exception e) {
            e.printStackTrace();
            callback.onWriteFailed(e.toString());
        }
    }

    public static PdfReader removeCrypto(Context context, PdfReader pdfReader) throws Exception {
        //System.out.println("清除密码");
        File file = IOUtil.createCacheFile(context, System.currentTimeMillis() + ".pdf");
        PdfReader.unethicalreading = true;
        PdfStamper stamper = new PdfStamper(pdfReader, new FileOutputStream(file));
        stamper.setEncryption(null, null,
                PdfWriter.ALLOW_ASSEMBLY
                        | PdfWriter.ALLOW_COPY
                        | PdfWriter.ALLOW_DEGRADED_PRINTING
                        | PdfWriter.ALLOW_FILL_IN
                        | PdfWriter.ALLOW_MODIFY_ANNOTATIONS
                        | PdfWriter.ALLOW_MODIFY_CONTENTS
                        | PdfWriter.ALLOW_PRINTING
                        | PdfWriter.ALLOW_SCREENREADERS,
                false);
        stamper.close();
        UriReader uriReader = UriReader.fromFile(context, file);
        return new PdfReader(uriReader.openAutoCloseInputStream());
    }

}
